home *** CD-ROM | disk | FTP | other *** search
/ Freaks Macintosh Archive / Freaks Macintosh Archive.bin / Freaks Macintosh Archives / Cracking / Crack-It-Up.sit / Crack-It-Up / Crack-It-Up.rsrc / styl_152.rtf < prev    next >
Text File  |  2000-01-29  |  35KB  |  4 lines

  1. {\rtf1\ansi
  2. {\fonttbl\f0\fswiss Courier;}
  3. {\colortbl\red255\green255\blue255;}
  4. \f0\b0\i0\outl0\shad0\fs20 \cf0 \expan0 \ul0 e.  Just leave all options as is, and hit return. Nosy will go through what it terms a TreeWalk which means that it will recursively analyze the program and generate it's decompiled code.\line Working with Nosy.\line Since I don't want to re-type the entire Nosy manual, I am going to list just the basics.  There are some great features that I never use and don't even know how to initiate without referring to the manual and these will be omitted.  Everything I use to crack software will be covered in detail.\line At this point, Nosy will present you with several windows: a Code Blks window, listing all procedures in the decompiled file; a Notes window which Nosy will use to display information; and a Mystery window, listing things that Nosy had trouble with during decompilation.  Nosy can also display a list of all Data Blocks which are chunks of code that either did not make sense as executable code, or were referenced as data (Nosy looks for PEA and LEA to determine this and looks for JMP, JSR, and BSR to find individual procedures).  Notes cannot be closed, so ignore it, and Mystery has things that - to date at least - don't matter that much to the cracker.  When working with Nosy, you can at any time select the name of a code or data block and hit CMD-d to display it in a new window.   Before examining the menu commands, lets look at a basic Nosy listing and see what Nosy tells us.\line \'0CThis is the procedure called Eject from the file Font/DA Mover.  This is the file I will describe in detail later.\line \line    BD4:                                 QUAL    Eject ; b# =79  s#1  =proc47\line \line                                vbt_1     VEQU  -64\line                                param2    VEQU  8\line                                param1    VEQU  10\line                                funRslt   VEQU  14\line    BD4:                                 VEND    \line \line                                ;-refs -  2/CLOSEMYF  \line \line    BD4: 4E56 FFC0      'NV..'  Eject    LINK    A6,#-$40\line    BD8: 41EE FFC0      200FFC0          LEA     vbt_1(A6),A0\line    BDC: 316E 0008 0016 2000008          MOVE    param2(A6),ioVRefNum(A0)\line    BE2: 216E 000A 0012 200000A          MOVE.L  param1(A6),ioNamePtr(A0)\line    BE8: A017           '..'             _Eject  ; (A0|IOPB:ParamBlockRec):D0\\OSErr \line    BEA: 3D40 000E      200000E          MOVE    D0,funRslt(A6)\line    BEE: 4E5E           'N^'             UNLK    A6\line    BF0: 225F           '"_'             POP.L   A1\line    BF2: 5C8F           '\\.'             ADDQ.L  #6,A7\line    BF4: 4ED1           'N.'             JMP     (A1)\line \line OK, The first column contains the code resource-relative address of the instructions.  To the right of this is the hex listing of the instruction, followed by an ascii display, followed by the actual assembly instruction.\line The first line tells you the following:  The name of the procedure (either a meaningful name Nosy found somewhere, or a generic procN where N tells where the procedure falls sequentially in the file), the block number (similar to proc number except this takes into account data blocks as well as procedure blocks), the segment or CODE resource ID #, and the actual procedure number.  So in the above example, we are looking at Eject, it is the 79th block in the file (counting data blocks), it is in code resource ID 01, and it is the 47th procedure block in the file.  So we could open CODE 01 in Resedit, skip down to BD8 and see the hex codes that Nosy lists.  Whe BD8 and not BD4 like it says above?  Well, on disk, a CODE resource has 4 header bytes (whose meaning escapes me at the moment) so we have to add 4 to the Nosy address to find the correct Resedit address.\line Below this information will be listed any local variables used (they will always contain an underscore) along with their relative offsets from the procedure, then any parameters passed along with their offsets.  If there is a result that will be passed back to the calling procedure, it will be listed as funRslt (as it is here).  Don't worry about all the offset information as Nosy will refer to parms and local variables by their symbolic names.  VEND denotes the end of the variable list.  Next comes any references to this procedure - any procedures that call this procedure.  Finally comes the actual listing.  Occasionally, Nosy will stick more than one procedure in a window.  If this happens, each procedure will have the above header.  Nosy also might include data blocks in a procedure's window and it will have the word dataXX to the left of it.\line \line \'0CMenu Commands\line \line \'01\line \line This is pretty straight forward and should require no explanation.  Save As... will allow you to save as text a procedure or data window.  This way you can type in your own comments and save them.  I never use this feature, however.  TTY mode allows some of Nosy's extra features.  In previous version, TTY was the only mode and I imagine was hell to use.  With the newer version, 2.0 or higher I believe, you can stay in the window mode that you are currently in and never use TTY mode.\line \'0C\'01\line \line OK, the first two sections are standard.  Find will find the next occurence of whatever you have selected.  For example, you can select a local variable name and hit cmd-f to find the next time it occurs in the current window.  If nothing is selected, Nosy presents a dialog allowing you to enter a search string.\line Change\line brings up a standard search/replace dialog - similar to Word.\line Goto Line\line allows the user to goto a specified line number in the front window.\line Grab Clip & Find\line operates like Find except that the clipboard is used as the search string.\line Show Insert pt\line scrolls the window to display the cursor (if you had scrolled the cursor off the screen).\line insert pt to Top\line places the cursor at the top of the screen (line 1).\line sel to Notes\line copies the current selection into the Notes window.\line \line \'01\line \line Code|Data blk\line displays the currently selected code or data block in a new window.  For example if you select a procedure from the code blocks window and hit cmd-d, the procedure will be displayed in a new window.  If there is no current selection then Nosy will request a proc name via a dialog.\line Refs to\line Active only if a procedure name is selected.  Displays all procedures that call the selected procedure.  Using this, you can see any part of the program that is calling a particular procedure.\line Call chain\line Similar to Refs to.  Any procedure that calls the selected procedure is also treated with Refs to.  For example, you select a procedure called proc5.  Doing a Refs to shows all procs that call proc5 - let us say for example, pro10 and proc 15.  If you had selected proc5 and done a Call chain instead of Refs to, then first proc10 would be displayed along with any proc that called and so on backwards until the chain ends.  Then proc15 would be listed along with any procs that call it, and so on until the chain ends.  This is an excellent way of tracing a procedure that draws an error dialog back to the procedure that actually generated the error.\line Sys syms map\line Displays all system global variables along with any procedures that reference them.  An example might be the system global MemErr which contains any OS errors.  Nosy would display any procedures that reference MemErr - note that this command displays ALL system globals and their referencing procedures.\line Trap refs map\line This is a beauty.  This will list all traps called by the program and the procedures that call them.  If a program is asking for a key disk, use this command to search for procedures that call either ModalDialog or one of the Alert traps.\line Globals map\line Displays all program global variables and the procedures that use them.\line Rsrc map\line Lists all program resources, their lengths, and names if any.\line Strings\line Lists all strings and the procedures that reference them.  I am not sure what Nosy defines as a string, but try it on Font/DA Mover to see.\line Data Blks\line Displays a window listing all data blocks.\line Case jumps\line Displays any procs containing a structure that resembles a case statement.\line Mystery procs\line Opens the Mystery Procs window showing any procedures that Nosy was unsure how to handle.\line ROM Patch Info\line Unknown.  My outdated docs don't even mention this command.\line Bad Blks\line Displays information about any blocks that Nosy thought were code but contained illegal instructions so Nosy converted them to data blocks.  Encrypted code would fit into this category.\line Blk tbl\line Displays the following for all blocks: name, segment number (resource ID #), start address, and length.\line Code Blks\line Displays the Code Blks window listing all code blocks.\line \line \'01\line \line Review...\line Lets you review data blocks, optionally converting them to code blocks.  More on this later.\line Link Jmp to Tbl\line Defines the link between a mystery jump and and a data block.  To use it, select the address of a mystery JMP and choose the command.  More on Jump Tables later.\line Code to Data\line Converts a selected code block to a data block.  The blocks name won't change until the next Explore (see below).\line Is Proc\line Converts a selected data block to a code block.  The block's name won't change until the next Explore.\line JSR is JMP\line Tells Nosy that a JSR is really a JMP.  Sometimes a JSR is followed by data - which will look like jiberish code.  The called procedure then pops the return address off the stack and uses that address as a pointer to a data block with no intention of returning to the calling procedure.  To use this command, select the destination of the JSR (e.g. for JSR  proc100, select proc100) and choose this command.\line Explore\line Initiates a TreeWalk.  This allows Nosy to re-examine the program using any changes you might have made (i.e. converting data blocks to code blocks, etc).\line \'0C\'01\line \line Extract Comments\line Extracts comments from the selection (usually an entire procedure window) into a window entitled Comments.  See section on commenting below.\line Append to .aci\line Appends selected comments (created using the above) to an aci (additional comment information) file.  Later, this file can be re-merged into the dissassembly.\line name cHange\line Changes the selected name to whatever you type in.  Use this to rename procedures from the generic procN to a name that tells you what the procedure basically does.  The change will be immediate and global.\line Addr to File pos\line Converts a selected address (the leftmost information for a procedure display) into file-relative information, displaying a file-relative offset (in hex), block or sector number, and the block offset to the start of the address.  This might be handy if you were using a file editor (instead of Resedit which allows you to simply open the proper code resource) to edit the file.\line Convert to .asm fmt\line Converts the current procedure window to asm format by removing the addresses and hex and ascii data.  Cannot be undone - you must close the window, not save changes, and re-open it.\line save .snt, reRead .aci\line Saves a .snt file for the dissassembled program and re-reads the comment file if it exists.  .snt files (saved Nosy tables) are a means of saving your dissassembly mid-session.  All changes are remembered so when you re-open the file later, you begin right where you left off instead of doing a TreeWalk all over again, etc.\line Journal commands\line A checkmark next to this indicates that all your commands are being saved to a text file.  The file will not actually be saved unless you specify so when you Quit - see quitting later.\line Proc rel addresses\line When checked displays the address of each instruction as procedure relative (starting at zero for each procedure instead of starting at zero for each code resource).\line format Maps by Addr\line When checked, Nosy will change the way it displays its various maps, i.e. Sys syms, Trap refs, etc. under the Display menu.  Instead of proc names, Nosy will display the segment number, and the segment offset.  But - if Proc rel addresses is also checked, then Nosy will replace the proc names with a proc name followed by a + followed by the procedure relative offset.  Try it out if this doesn't make sense.\line cmds to Notes Wind\line Not yet implementated - like a lot of great features (see below).\line Set Source Path\line Not in my manual - you're on your own.\line Extract Map Names\line Not in my manual - on you're own again.  This doesn't seem to do anything, though, when I try it.\line \line Unfortunately, the Search_Rsrc menu is totally disabled.  Maybe the next version...\line \line \'01\line \line Record/ALL names\line Lists all Macintosh data structures that Nosy currently knows.\line Fields of\line Depends on the selection:  1) a datatype (e.g. Dialog Record - or anything listed by the previous command) - describes all fields for the datatype.  2) datatype@address - displays the current values for the datatype if one exists at the specified address.  3) @address - displays hex/ascii dump at specified address.\line OS Traps\line Lists all known Operating System Traps and their parameters.\line TB Traps\line Lists all known ToolBox traps and their parameters.\line Sys Syms\line Lists all known System Symbols.\line Sys Errs\line Lists all known System Errors and their codes.\line Constants\line Lists all known Macintosh Constants.  Note that my copy of Nosy contains an error in this window - it specifies that constants in brackets can be selected and viewed by pressing cmd-?.  Use cmd-<space> (or select Fields of from the Tables menu).\line Ascii\line Decimal/Hex/Ascii lookup table.\line Calculate\line Evaluates selected expressions which can contain mathematical operators, system globals, program globals, IM datatypes,  registers etc.  Use # to force decimal (#10) and $ for hex ($10).\line Convert Hex to Dec\line Converts a selected number to decimal, ascii, and system symbol equivalent if there is one.\line add/ZAP Type /Defs\line No idea.\line \line Note on commands requiring a selection (Calculate, etc.)  You may have noticed that often there is no place to enter the text you want to select.  In cases like these, type your text into the Notes window, select it, and choose the command you wish.\line \line \'0CReviewing Data Blocks\line This is the process by which you tell Nosy that it has mistakenly made a piece of code a data block.  Once you initiate the Review... command, Nosy will show you each data block in sequence and give you a chance to work on it.  Note that you may never need to do this to crack a program - god knows I never use it unless I am really having problems.  This section is to provide you with some idea of what Nosy can do.\line Here is a typical display after selecting Review... from the Reformat menu.  The Data Blk window displays the data block, the window directly underneath this will display the section of code that references that data block (if their is one) and the Cmd window awaits your input.  There are about a zillion things you can do, but the most important one is the c command.\line \'01\line \'0CIf your press c and return, Nosy shows you what the data block looks like in assembly:\line \'01\line Notice that this looks like pretty good code!  Also note that Nosy has placed i in the Cmd window anticipating that you will want to change this to code.  Here are all the commands available:\line \line H\line takes 2 parameters: 1) either L,W, or B for Longword, Word, or Byte and 2) the number of entries per line.  Formats the block as Hex bytes.  Example: HL2 would format the block as hex longwords, 2 per line.\line D\line same as H (above) but formats block as decimal entries.\line A\line same as H (above) but formats the block as ascii entries.\line Z\line same as H (above) but formats the block as zero entries.\line W\line Formats the block as a word-aligned Pascal string.\line S\line Formats the block as a Pascal string.\line WZSTR\line Formats the block as a word-aligned zero-terminated string.\line Z\line Formats the block as a zero-terminated string.\line J\line Formats the block as a set of Jump Table entries - each word is taken as an offset from the beginning of the data block to a common procedure and these jumped to spots are marked as common blocks (a common block - denoted com_nn - is any procedure executed via JMP instead of JSR or BSR).  If you do this, you need to use the Link Jmp to Tbl command to link the jump table to its jump command.  See Jump Tables below.\line JUMPP\line Same as J except that the entry points are marked as procedures instead of common blocks.\line BRAL\line Formats the block as code.  Any instructions that are BRAnched to are marked with local markers (as in a standard Nosy listing).\line BRAC\line Same as above except that instructions reached via BRA are marked as common blocks.\line U\line Undoes any formatting changes.\line C\line Changes the block to a code listing and brings up the code menu - discussed below.\line Q\line Exits Review mode.\line N\line takes an integer parameter X.  Splits the block into two blocks, the first block getting X words (remember a word is two bytes).\line NB\line same as above except the parameter specifies bytes instead of words.\line NL\line same as above except the parameter is a segment-relative address specifying the end of the the first block.\line NU\line takes an optional search string as parameter.  Splits the block with the first block ending upon finding the search string.  If no string is supplied, Nosy searches for a logical procedure end (RTS, JMP(AX) ).  The block is formatted as code and the code menu is displayed.\line NW\line Splits the block in two, the first block being made a word-aligned Pascal string.\line N*\line Splits the block in two.  Uses the first longword to determine the length of the first block.\line O\line If the previous block is a data block, then combine it with the current one.\line ADDR\line Formats the block as a list of word-length procedure block addresses.\line LADRC\line Formats the block as a list of longword-length common block addresses.\line LADRP\line Formats the block as a list of longword-length procedure block addresses.\line <Return>\line Saves changes, and takes you to the next block.\line \line The Code Menu Commands:  these come up if you use c or nu to change the block to a code listing.\line \line U\line Undo any changes to size or format and takes you back to the Review menu.\line I\line Tells Nosy to keep the block as code and return to the Review menu.\line Q\line Exits Review mode.\line R\line Changes block back to data, but retains any size changes you may have made.\line N\line Same as the N commands above.\line <Return>\line Same as above - returns to the Review menu.\line \line Once you have finished Reviewing data blocks, you must select Explore from the Reformat menu to have Nosy incorporate any changes into its lists.\line \line \'0CWorking with Jump Tables\line \line A jump table is a means of efficiently transferring control to a procedure.  An example of a jump table would be a program that receives an event (as most mac programs do) and then has to execute a procedure depending on what the event was.  Font/DA Mover has an extermely simple jump table - actually it is not a true jump table - in which the button the user clicks is returned to its main event loop as an integer.  The program then repeatedly subtracts one from the integer and branches to an appropriate procedure when the integer has been reduced to zero.  A more common (and true) jump table consists of a list of offsets.  The program then takes an integer which tells it which entry in the table to use, multiplies it by 2 (assuming each entry is two bytes in length) and then indirectly jumps to the correct procedure.  Here is an example taken from the Nosy manual (this is from the System File's .MPP driver):\line \line LEA\line data4,A3\line ADDA\line D3,A3\line ADDA\line D3,A3\line MOVEA\line (A3),A3\line PEA\line .MPP\line ADDA.L\line (A7)+,A3\line JMP\line (A3)\line \line data4\line DC.W\line $82,$280,$26C,$3C, etc\line \line As gross as this looks, lets see what it is doing.  At the start, D3 contains the selector that determines which entry in the table to use.  A3 is loaded with the address of the jump table.  D3 is added to it twice (we could have doubled D3, then added it) so that now A3 contains the address of the proper jump table entry.  The instruction MOVEA   (A3),A3 grabs the jump table entry (which is simply an offset from the start of the program to the correct procedure) and puts that entry back into A3.  Next the address of the program start (.MPP) is pushed on the stack, and this value is added to A3 to produce the actual address of the procedure (the address is the start of the program plus the offset).  Now A3 is setup, so the program Jumps to the address in A3.  If you don't mind looking at this type of listing (and I don't since it probably is not the copy protection - although it might be jumping to the copy protection) then you need go no farther.  But Nosy can set this up to look much nicer.\line To fix this up, select the address (the far left column) of the Jump instruction - in this case, the JMP (A3).  Now choose Link Jmp to Tbl from the Reformat menu and a dialog box appears requesting the name of the jump table's block - in our case that would be data4.  Click continue and a new dialog appears.  The first thing we need is the table format.  There are three choices: JUMPP - tells nosy to label the jumped to procedures as procedure blocks; JUMPC - tells Nosy to label the jumped to procedures as common blocs; JUMPL - tells Nosy to label the jumped to procedures with local labels in the same block as the jump table.  To figure out which one to use (and it is really a matter of preference), decide if you want to break the whole thing up into many procedures, or keep it as one large procedure with tons of local labels.  If the procedure is a massive one, you may want to break it up (and I would recommend JUMPP - but then, I like proc labels better than com labels), otherwise, use JUMPL.\line Next we need the number of jumps.  Just count the number of entries - but be careful: you need to decide the size of each entry in the table.  Note the DC.W  next to data4.  This means that Nosy is showing you individual words so you can just count the number of entries.  But if Nosy is using DC.B, then it is showing you bytes, so you would have half as many word length entries.\line Finally, we need the Table Bias.  Bias is a parameter that Nosy uses to determine the actual procedure address of a non-standard jump table.  To calculate this, use this formula:  Bias = Address of JumpTable + Offset - TargetAddress.  The tricky thing is to deterine the TargetAddress.  In the above example, it is easy, since the code clearly refers to the start of itself (it refers to the address of .MPP).  JumpTable is the address (leftmost column in the listing) of the start of the jump table, and Offset is the first word-length offset in the table.  Note that your calculations will result in a hex bias - Nosy needs you to change it to decimal.\line \'0CClick Accept, do another Explore, and that is it!  Now the listing looks like:\line \line \line JMP\line (A3)\line \line \line JBIAS\line 92\line data4\line JUMP\line procA\line \line JUMP\line procB\line \line JUMP\line procC\line \line etc.\line Notice that Nosy uses JUMP to distinguish it from the instruction JMP.  Once this is set up, it is a cinch to see where the jump table is jumping - provided you can deduce the selector.  Most of the time Nosy works wonders with jump tables, and the few times it has problems (it will list these problems in the Mystery window) I have found it not worth the work to convert them to the above format.\line Commenting Your Listings\line \line There are a couple of cool features that I am not going to explain regarding commenting simply because I have never used them and the manual I have isn't the most verbose.  Basically, you can put comments on any line that Nosy hasn't already commented.  All comments must start with a semi-colon.  Once you have all the comments you want, do a cmd-a to select all, and choose Extract Comments from the Misc menu.  Nosy will extract all your comments into a comments window.  Now hit cmd-a again, and choose Append to .aci from the Misc menu.  This will save your comments.  Now close the procedure window and don't save changes.  Select Save .snt, reRead .aci from the Misc menu.  Nosy may ask you if you want to delete something or other which it claims saves space in the Debugger.  Since we are not using the Debugger, choose No.  Now when you open the procedure again, you comments appear.\line There is one feature I will attempt to explain, because it could be a serious boon.  There a several slash (/) commands Nosy understands.  One in particular, /w, works like this:  Anytime a register is setup to contain a pointer to a Mac structure, you can have Nosy automatically show the structure whenever the register is referenced.  Here is an example:\line \line \line \line PEA\line data24\line \line ; len = 206\line \line \line _OpenPort  ;  (port:GrafPtr)\line \line \line LEA\line data24,A2\line ; len = 206\line \line \line MOVE\line #4,68(A2)\line \line \line MOVE\line #9,74(A2)\line \line Note in the 3rd line that A2 is given the GrafPtr.  Since GrafPtr is a pointer to a valid Mac structure (GrafPort), we could use the /w command as follows:  click at the end of the 3rd line and hit return (so we are not commenting on a line that Nosy has already commented).  Enter /w<space>GrafPort.  Now save the comments as illustrated above.  When the proc is re-opened it shows the following:\line \line \line \line PEA\line data24\line \line ; len = 206\line \line \line _OpenPort  ;  (port:GrafPtr)\line \line \line LEA\line data24,A2\line \line \line /w GrafPort\line \line \line MOVE\line #4,txFont(A2)\line \line \line MOVE\line #9,txSize(A2)\line \line Using this technique, Nosy will use the fields of the structure instead of the actual offsets from the register.  This will work for any valid Mac structure.  I haven't used this feature (I just noticed it when compiling this manual) so that is all I will say - feel free to experiment.\line Well, I guess the next thing to do is start looking at some serius code listings pulled directly from Nosy (and not stuff I made up on the fly).  Nosy has shorthand notations for certain operations, most commonly for stack operations.  The two to watch out for are PUSH and POP (btw, TMON does not use this notation, but rather uses the standard notation found in any assembly book).  PUSH is the equivalent of putting the operand onto the stack using auto pre-decrement.  POP is the same as grabbing the operand off the stack using auto post-increment.\line Let's take a look at some code listings from Font/DA Mover 3.8.  I selected this program so that you can pull up the same listings that I will refer to in Nosy.  First take a look at the initial procedure:  DA Mover.  There will always be a procedure whose name is the same as the program you are de-compiling.  This procedure (DA Mover in this case) is the first procedure the program executes when launched.\line \line    430:                                 QUAL    DA Mover ; b# =12  s#1  =proc4\line \line OK, I will stick my notes right in the listing (below or to the right of what I am refering to), so bear with me.  Note the first line (above).  We are looking at block 12, segment (or CODE resource #) 1, and it is the 4th procedure in the program.\line The first few lines will do some startup stuff that I do not fully understand and so I will skip it.\line    430: 4EBA 0C48      100107A DA Mover JSR     proc70\line Proc 70 is just an RTS\line    434: 4E56 0000      'NV..'           LINK    A6,#0\line    438: 2C5F           ',_'             POP.L   A6\line    43A: 4EBA 0C40      100107C          JSR     proc71\line Proc 71 calls _RTINIT which seems to be a common step for MPW compiled programs.  It then initializes some global variables.  Let's skip all this.\line    43E: 486D 024A      3000000          PEA     proc232(A5)\line    442: A9F1           '..'             _UnLoadSeg ; (Proc:ProcPtr)  Here we are dumping an un-needed procedure.\line Now, looking at the listing from here, notice the procedures that get called - two without labels, then SetUp, MakeAWin and FinderSE and finally MainEven which sounds suspicially like an event loop.  Let's check out these procedures.\line    444: 4EBA 05E2      1000A28          JSR     proc28\line If you look at this procedure, you see several references to memory stuff like ApplHeap, ApplZone, Rom85, etc.  Looks like this is checking for enough memory or something.  Not too interesting.\line    448: 4EBA 021E      1000668          JSR     proc10\line This proc looks to be changing a few traps.  Note that it allocates a new pointer (NewPtr trap) and then calls GetTrapAddress, and then SetTrapAddress.\line    44C: 4EAD 01F2      2005092          JSR     SETUP(A5)\line Take a look at this listing below the current one:\line    450: 4EAD 01FA      2005852          JSR     MAKEAWIN(A5)\line Draw the main dialog.\line    454: 4EBA FCC2      1000118          JSR     FINDERSE\line Checks if user launched a suitcase and if so, opens it.\line    458: 4AAD F4F0        -$B10          TST.L   glob26(A5)\line Verify the main memory handle.\line    45C: 6706           1000464          BEQ.S   lae_1\line Branch if it is empty.\line    45E: 4EBA FBA0      1000000          JSR     MAINEVEN\line Do the actual program until user Quits.\line    462: 6008           100046C          BRA.S   lae_2\line Exit without error.\line    464: 3F3C 0031      '?<.1'  lae_1    PUSH    #49\line Out of Memory Error.\line    468: 4EAD 01CA      200023C          JSR     DOALERT(A5)\line Do an Out of Memory alert\line    46C: 4EBA FF86      10003F4 lae_2    JSR     DOCLEANU\line From here, the program exits.\line    470: 4EAD 01D2      20002B2          JSR     MYEXITTO(A5)\line    474: 4EBA 0C2A      10010A0          JSR     %INITHEA\line    478: 4EBA 0C2C      10010A6          JSR     proc73\line    47C: 4E75           'Nu'             RTS     \line \line    47E: 4E5E 4E75 C64F 4E54    data9    DNAME   FONT_DA_,4\line \line    48A: '..'                   data10   DC.W    0\line Here is the SetUp Procedure:\line \line   5092:                                 QUAL    SETUP ; b# =467  s#2  =proc199\line \line                                vho_1     VEQU  -12\line Only one local variable, no parameters.\line   5092:                                 VEND    \line \line                                ;-refs -  1/DA Mover  \line Only called via DA Mover.\line \line   5092: 4E56 FEE6      'NV..'  SETUP    LINK    A6,#-$11A\line Setup a Stack frame for local variables\line   5096: 48E7 0118      'H...'           MOVEM.L D7/A3-A4,-(A7)\line Save D7,A3 and A4 on stack\line   509A: 7E01           '~.'             MOVEQ   #1,D7\line Loop coming up, this inits the loop counter.\line   509C: 6006           20050A4          BRA.S   lho_2\line And branch into the loop.\line \line   509E: 4EAD 00D2      1000AB0 lho_1    JSR     MoreMasters(A5)\line   50A2: 5247           'RG'             ADDQ    #1,D7\line Increment loop counter.\line   50A4: 700F           'p.'    lho_2    MOVEQ   #15,D0\line   50A6: B047           '.G'             CMP.W   D7,D0\line Test if loop done...\line   50A8: 6CF4           200509E          BGE     lho_1\line If not, branch back.\line OK, take a look at the above code.  First, D7 is initialized to 1 and then the program branches down to lho_2.  The loop test is setup here (15 is the end of the loop).  At the compare, ask yourself, is D0 greater than or equal to D7?  Well, the first time, D0 is 15 and D7 is 1 so the loop branch will execute.  So, MoreMasters is called, 1 is added to the loop counter, and then the loop is checked again.  This will loop 15 times (until D7 has 16 in it).  MoreMasters is a trap (in this case, the procedure called MoreMasters will execute the trap) that causes a block of master pointers to be allocated in the current heap zone.  See Inside Mac's (here on referred to as IM) Memory Manager section for a better description.\line   50AA: 486D F420        -$BE0          PEA     glob3(A5)\line Push the address of glob3 on the stack.\line   50AE: A86E           '.n'             _InitGraf ; (globalPtr:Ptr) InitGraf, we see in IM, that InitGraf must be called once near the start of a program.  It requires one parameter, a pointer to the first QD global variable. This parameter is first pushed on the stack in the previous instruction.\line   50B0: A8FE           '..'             _InitFonts  \line These traps can all be found in IM.\line   50B2: A912           '..'             _InitWindows  \line   50B4: 2F3C 0000 FFFF '/<....'         PUSH.L  #$FFFF\line   50BA: 201F           ' .'             POP.L   D0\line   50BC: A032           '.2'             _FlushEvents ; (whichMask,stopMask:EventMask) \line   50BE: A9CC           '..'             _TeInit  \line   50C0: 42A7           'B.'             CLR.L   -(A7)\line Note that InitDialogs needs a ProcPtr (a long word).  The clr command here uses auto pre-decrement to push a NIL pointer onto the stack.\line   50C2: A97B           '.{'             _InitDialogs ; (resumeProc:ProcPtr) \line   50C4: A930           '.0'             _InitMenus  \line   50C6: 486E FFF4      200FFF4          PEA     vho_1(A6)\line OK, notice the VAR in the trap below.  This means that info will be returned via the parameter we push on the stack.  So, after the trap, vho_1 will be a GrafPtr (whereas before the trap, god knows what is in it).\line   50CA: A910           '..'             _GetWMgrPort ; (VAR wPort:GrafPtr) \line   50CC: 2F2E FFF4      200FFF4          PUSH.L  vho_1(A6)\line Now, our GrafPtr is used to set the current Port.\line   50D0: A873           '.s'             _SetPort ; (port:GrafPtr) \line   50D2: 206E FFF4      200FFF4          MOVEA.L vho_1(A6),A0\line Now A0 contains our GrafPtr.\line   50D6: 4868 0008      'Hh..'           PEA     8(A0)\line This instruction says to add 8 to A0,and push that address on the stack.\line   50DA: A87B           '.{'             _ClipRect ; (r:Rect) \line   50DC: 2F3C 000E 000C '/<....'         PUSH.L  #$E000C\line The MoveTo trap requires two integers to be passes, but only one value is being pushed on the stack.  Since the instruction says to push l}